# -*- coding: utf-8 -*-
"""工具函数模块

包含游戏中所有的辅助工具函数
"""

from typing import Dict

from .const import TildeType
from .object import GameState


def calculate_distance(pos1: Dict[str, int], pos2: Dict[str, int]) -> int:
    """计算两点之间的曼哈顿距离

    Args:
        pos1: 位置1 {x, y}
        pos2: 位置2 {x, y}

    Returns:
        曼哈顿距离
    """
    return abs(pos1['x'] - pos2['x']) + abs(pos1['y'] - pos2['y'])


def calculate_legal_distance(pos1: Dict[str, int], pos2: Dict[str, int]) -> int:
    """计算两点之间的合法距离（只允许水平或垂直移动）

    Args:
        pos1: 位置1 {x, y}
        pos2: 位置2 {x, y}

    Returns:
        合法距离，如果不能直接到达则返回-1
    """
    dx = abs(pos2['x'] - pos1['x'])
    dy = abs(pos2['y'] - pos1['y'])

    # 只允许水平或垂直方向，不允许对角线
    if dx > 0 and dy > 0:
        return -1  # 不能直接到达

    # 返回水平或垂直距离
    return max(dx, dy)


def is_in_range(from_pos: Dict[str, int], to_pos: Dict[str, int], range_val: int) -> bool:
    """检查位置是否在范围内（只允许水平或垂直方向，不允许对角线）

    Args:
        from_pos: 起始位置 {x, y}
        to_pos: 目标位置 {x, y}
        range_val: 范围

    Returns:
        是否在范围内
    """
    legal_distance = calculate_legal_distance(from_pos, to_pos)
    return legal_distance != -1 and legal_distance <= range_val


def get_direction_to(from_pos: Dict[str, int], to_pos: Dict[str, int]) -> Dict[str, int]:
    """获取从起点到终点的方向

    Args:
        from_pos: 起始位置 {x, y}
        to_pos: 目标位置 {x, y}

    Returns:
        方向向量 {x, y}
    """
    dx = to_pos['x'] - from_pos['x']
    dy = to_pos['y'] - from_pos['y']

    if abs(dx) > abs(dy):
        return {'x': 1 if dx > 0 else -1, 'y': 0}
    else:
        return {'x': 0, 'y': 1 if dy > 0 else -1}


def get_position_state(input: GameState, pos: Dict[str, int]) -> str:
    if not is_valid_position(input, pos):
        return 'invalid'

    # 检查地形是否可移动：只有平地可以移动，河流和其他地形都阻隔移动
    tile = input.getTilde(pos['x'], pos['y'])
    if not tile or tile.type != TildeType.flat:
        return 'block'  # 河流、山丘、资源地形等都阻隔移动

    # 检查是否有存活的单位
    for unit in input.units.values():
        if unit.hp > 0 and unit.x == pos['x'] and unit.y == pos['y']:
            return 'unit'

    # 检查是否有存活的建筑
    for building in input.buildings.values():
        if building.hp > 0 and building.x == pos['x'] and building.y == pos['y']:
            return 'building'

    return 'empty'


def is_valid_position(input: GameState, pos: Dict[str, int]) -> bool:
    """检查位置是否有效

    Args:
        input: 游戏状态
        pos: 位置 {x, y}

    Returns:
        位置是否有效
    """

    return 0 <= pos['x'] < input.battleState.width and 0 <= pos['y'] < input.battleState.height
